#include "tabu_list.h"

TabuList::TabuList(size_t length) 
	:max_length_(length) {}


void TabuList::Push(const Element& new_element) {
	Push(SimpleCRC(new_element));
}


bool TabuList::Has(const Element& element) const {
	crc_t key = SimpleCRC(element);
	return Has(key);
}


auto TabuList::SimpleCRC(Element element) -> crc_t {
	static const crc_t G = 34943; // CRC constant
  crc_t crc = 0;
	for (int e : element) {
      crc = ( (crc << 8) | e) % G;
  }
  crc <<= 16;
  return crc % G;
}


void TabuList::Pop() {
	crc_t out = crc_queue_.front();
	crc_queue_.pop();
	crc_set_.erase(out);
}


void TabuList::Push(crc_t key) {
	if (!Has(key)) {
		if (crc_queue_.size() >= max_length()) {
			Pop();
		}

		crc_queue_.push(key);
		crc_set_.insert(key);
	}
}